package com.smart.common.handler;


import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonStreamContext;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.smart.common.entities.core.BaseEnum;
import com.smart.common.exception.SmartException;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;

/**
 * 接收BaseEnum反序列化
 *
 * @author xiaxuqiu
 */
@Log4j2
public class BaseEnumDeserializer extends JsonDeserializer<BaseEnum> {

    @SuppressWarnings({"rawtypes"})
    @Override
    public BaseEnum deserialize(JsonParser parser, DeserializationContext context) throws IOException {

        JsonNode node = parser.getCodec().readTree(parser);
        String currentName = parser.currentName();
        Object currentValue = parser.getCurrentValue();
        Class findPropertyType = null;
        if (currentValue instanceof Collection) {
            JsonStreamContext parsingContext = parser.getParsingContext();
            JsonStreamContext parent = parsingContext.getParent();
            Object currentValue3 = parent.getCurrentValue();
            String currentName3 = parent.getCurrentName();
            try {
                Field listField = currentValue3.getClass().getDeclaredField(currentName3);
                ParameterizedType listGenericType = (ParameterizedType) listField.getGenericType();
                Type listActualTypeArguments = listGenericType.getActualTypeArguments()[0];
                findPropertyType = (Class) listActualTypeArguments;
            } catch (Exception e) {

                e.printStackTrace();
            }
        } else {
            findPropertyType = BeanUtils.findPropertyType(currentName, currentValue.getClass());
        }
        if (findPropertyType == null) {
            throw new SmartException("数据格式异常");
        }


        //尝试在对象模式内获取元素
        String objValue = node.findPath("value").asText();
        String enumName = StrUtil.isNotBlank(objValue) ? objValue : node.asText();
        return StrUtil.isNotBlank(enumName) ? BaseEnum.getEnum(enumName, findPropertyType) : null;
    }


}